import { MessageType } from "@/types/chat.ts";
import { ChatType, IMessage } from "@/types/chat";
import { IInsertParams, ISession } from "@/types/session";
import { defineStore } from "pinia";
import { ref, toRaw } from "vue";
import { BuildNewSession, BuildSessionContent } from "@/utils/common";
import { useChat } from "./chat";
import { useUser } from "./user";
import { ElMessage } from "element-plus";
import { useCache } from "./cache";

interface IMatchRes {
  session: ISession | null;
  index: number;
}

export const useSession = defineStore("session", () => {
  const user = useUser();
  const chat = useChat();
  const cache = useCache();
  let SessionList = ref<ISession[]>([]);
  let GlobalUnreadMessage = ref(0);

  // 添加session
  async function AddSession(params: IInsertParams): Promise<void> {
    const { avatar, name, ...restParams } = params;
    const newSession = {
      updatedAt: new Date().toISOString(),
      isPinned: 0,
      isDel: 0,
      ...restParams,
    };
    try {
      const { session: existingSession, index } = MatchMessage(params.sessionId);
      // 如果存在覆盖就行
      if (existingSession) {
        let data = { ...newSession, ...existingSession, unread: 0 };
        appendSession(data, index);
      } else {
        // 不存在 添加
        const addedSession = await window.electronApi.addSession(newSession);
        let data = { ...addedSession, name, avatar };
        appendSession(data as ISession, index);
      }
    } catch (error) {
      console.error("添加session失败", error);
    }
  }

  // 更新session
  function UpdateSession(message: IMessage, isLocal: boolean = false) {
    let { session, index } = isMatch(message);
    if (!session) {
      session = BuildNewSession(message, isLocal);
    } else {
      session.content = BuildSessionContent(message);
      session.sessionType = message.messageType;
      session.updatedAt = new Date().toString();
    }
    // 插入到已经有的session会话里面
    appendSession(session, index);
    // 更新本地会话表
    window.electronApi.storeLocalSession(toRaw(session));
  }

  //匹配session
  function isMatch(message: IMessage): IMatchRes {
    // 如果为空直接插入
    if (SessionList.value.length === 0) return { session: null, index: -1 };
    switch (message.chatType) {
      case ChatType.friendNotify:
        return MatchNotify();
      default:
        return MatchMessage(message.sessionId);
    }
  }

  // 匹配通知
  function MatchNotify(): IMatchRes {
    const index = SessionList.value.findIndex((item) => item.sessionType === MessageType.requestAdd);
    if (index === -1) return { session: null, index };
    const matchedItem = SessionList.value[index];
    if (matchedItem.unread === 0) matchedItem.unread = 1;
    else matchedItem.unread += 1;
    return { session: matchedItem, index };
  }

  // 匹配消息
  function MatchMessage(sessionId: string): IMatchRes {
    const index = SessionList.value.findIndex((item) => item.sessionId === sessionId);
    if (index === -1) return { session: null, index };
    const matchedItem = SessionList.value[index];
    // 判断是不是当前聊天对象 如果不是unread+1
    if (matchedItem.sessionId != chat.ChatObject?.sessionId) {
      matchedItem.unread++;
    }
    return { session: matchedItem, index };
  }

  //置顶
  async function PinnedSession(sessionId: string, status: boolean = false) {
    const session = SessionList.value.find((s) => s.sessionId === sessionId);
    if (!session) return;
    const res = await window.electronApi.togglePinSession({
      sessionId,
      ownerId: user.userId!,
      pinState: status,
    });
    if (!res) {
      ElMessage.error("置顶失败");
      return;
    }
    session.isPinned = status ? 1 : 0;
    SessionList.value.sort((a, b) => b.isPinned - a.isPinned);
    ElMessage.success(status ? "置顶成功" : "取消置顶成功");
  }

  //移除会话
  async function RemoveSession(sessionId: string) {
    let res = await window.electronApi.softDeleteSession(sessionId, user.userId!);
    if (!res) {
      ElMessage.error("置顶删除会话失败");
      return;
    }
    if (sessionId === chat.ChatObject?.sessionId) chat.ResetChatState();
    SessionList.value = SessionList.value.filter((s) => s.sessionId != sessionId);
  }

  // 移除未读消息
  async function RemoveUnread(sessionId: string, needRequest: boolean = true) {
    UpdateSessionByField(sessionId, { unread: 0 });
    if (!needRequest) return;
    await window.electronApi.handelUnread(sessionId, user.userId!);
  }

  // 获取最近session消息
  async function GetSessionChatList() {
    let res: any = await window.electronApi.getLocalSession(user.userId!);
    if (!res) {
      ElMessage.error("获取session失败");
      return;
    }
    SessionList.value = mergeSession(res);
  }

  // 根据字段更新session
  async function UpdateSessionByField(
    sessionId: string,
    data: Partial<Omit<ISession, "sessionId" | "ownerId">>,
    needUpdateDataBase: boolean = false,
  ) {
    if (!SessionList.value.length) return;
    const session = SessionList.value.find((s) => s.sessionId === sessionId);
    if (!session) return;
    if (needUpdateDataBase) {
      const res = await window.electronApi.updateSessionByField(sessionId, user.userId!, data);
      if (!res) {
        console.error("更新session出错");
        return;
      }
    }
    Object.assign(session, data);
  }

  // 排序策略
  function appendSession(session: ISession, index: number) {
    if (index !== -1) SessionList.value.splice(index, 1);

    const lastPinnedIndex = (() => {
      for (let i = SessionList.value.length - 1; i >= 0; i--) {
        if (SessionList.value[i].isPinned) return i;
      }
      return -1;
    })();

    const insertIndex = session.isPinned ? 0 : lastPinnedIndex === -1 ? 0 : lastPinnedIndex + 1;

    SessionList.value.splice(insertIndex, 0, session);
  }

  // 查询本地的name avatar 合并到session
  function mergeSession(result: any): ISession[] {
    return result.map((item: any) => {
      const { chatType, toId } = item;
      if (chatType === ChatType.group) {
        const groupdata = cache.GetGroupInfo(toId);
        return {
          ...item,
          name: groupdata?.name || "",
          avatar: groupdata?.avatar || "",
        };
      }
      if (chatType === ChatType.friend) {
        const friendInfo = cache.GetFriendInfo(toId);
        return {
          ...item,
          name: friendInfo?.name || "",
          avatar: friendInfo?.avatar || "",
        };
      }
      return { ...item, name: "", avatar: "" };
    });
  }
  // 下线同步本地session到本地数据
  // TODO:尝试下线的时候更新本地数据库session
  function StoreSession() {}

  return {
    SessionList,
    GlobalUnreadMessage,
    GetSessionChatList,
    UpdateSession,
    RemoveSession,
    PinnedSession,
    AddSession,
    RemoveUnread,
    UpdateSessionByField,
    StoreSession,
  };
});
